package com.ruoyi.system.service.impl;

import java.util.Date;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.EntityRent;
import com.ruoyi.system.domain.ResultMap;
import com.ruoyi.system.mapper.EntityRentMapper;
import com.ruoyi.system.service.IEntityDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.RentDeviceLinkMapper;
import com.ruoyi.system.domain.RentDeviceLink;
import com.ruoyi.system.service.IRentDeviceLinkService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import static com.ruoyi.common.constant.RentConstants.*;
import static com.ruoyi.common.core.domain.AjaxResult.CODE_TAG;

/**
 * 【请填写功能名称】Service业务层处理
 * 
 * @author ruoyi
 * @date 2020-12-27
 */
@Service
public class RentDeviceLinkServiceImpl implements IRentDeviceLinkService {
    @Autowired
    private RentDeviceLinkMapper rentDeviceLinkMapper;
    @Autowired
    private EntityRentMapper entityRentMapper;
    @Autowired
    private IEntityDeviceService iEntityDeviceService;
    /**
     * 查询【请填写功能名称】
     * 
     * @param id 【请填写功能名称】ID
     * @return 【请填写功能名称】
     */
    @Override
    public RentDeviceLink selectRentDeviceLinkById(Long id)
    {
        return rentDeviceLinkMapper.selectRentDeviceLinkById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     * 
     * @param rentDeviceLink 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<RentDeviceLink> selectRentDeviceLinkList(RentDeviceLink rentDeviceLink)
    {
        return rentDeviceLinkMapper.selectRentDeviceLinkList(rentDeviceLink);
    }

    /**
     * 新增【请填写功能名称】
     * 
     * @param rentDeviceLink 【请填写功能名称】
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertRentDeviceLink(RentDeviceLink rentDeviceLink) {
        if(null != rentDeviceLink.getPlanRentStartTime() && null != rentDeviceLink.getPlanRentEndTime()){
            int planRentSpan = DateUtils.differentDaysByMillisecond(rentDeviceLink.getPlanRentEndTime(), rentDeviceLink.getPlanRentStartTime()) + 1;
            rentDeviceLink.setPlanRentSpan(planRentSpan);
        }
        return rentDeviceLinkMapper.insertRentDeviceLink(rentDeviceLink);
    }

    /**
     * 修改【请填写功能名称】
     * 
     * @param rentDeviceLink 【请填写功能名称】
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateRentDeviceLink(RentDeviceLink rentDeviceLink){
        RentDeviceLink link = selectRentDeviceLinkById(rentDeviceLink.getId());
        if(RENT_TYPE_RENTING != link.getValid()){
            return AjaxResult.error("选择归还设备，目前不是已出租状态，无法更新！");
        }
        if(null != rentDeviceLink.getPlanRentStartTime() && null != rentDeviceLink.getPlanRentEndTime()){
            int planRentSpan = DateUtils.differentDaysByMillisecond(rentDeviceLink.getPlanRentEndTime(), rentDeviceLink.getPlanRentStartTime()) + 1;
            rentDeviceLink.setPlanRentSpan(planRentSpan);
        }
        if(null != rentDeviceLink.getActualRentStartTime() && null != rentDeviceLink.getActualRentEndTime()){
            int actualRentSpan = DateUtils.differentDaysByMillisecond(rentDeviceLink.getActualRentEndTime(), rentDeviceLink.getActualRentStartTime()) + 1;
            rentDeviceLink.setActualRentSpan(actualRentSpan);
        }
        int result = rentDeviceLinkMapper.updateRentDeviceLink(rentDeviceLink);
        return 1==result?AjaxResult.success():AjaxResult.error();
    }

    /**
     * 删除【请填写功能名称】对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteRentDeviceLinkByIds(String ids)
    {
        return rentDeviceLinkMapper.deleteRentDeviceLinkByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除【请填写功能名称】信息
     * 
     * @param id 【请填写功能名称】ID
     * @return 结果
     */
    @Override
    public int deleteRentDeviceLinkById(Long id)
    {
        return rentDeviceLinkMapper.deleteRentDeviceLinkById(id);
    }

    /**
     * 按照设备类型统计，设备出租的次数
     * @return
     */
    @Override
    public JSONObject queryEveryDeviceTypeRentCount(){
        JSONObject jsonObject = new JSONObject();
        JSONArray arrayName = new JSONArray();
        JSONArray arrayValue = new JSONArray();
        List<ResultMap> resultMaps = rentDeviceLinkMapper.queryEveryDeviceTypeRentCount();
        if(!CollectionUtils.isEmpty(resultMaps)){
            for(ResultMap result : resultMaps){
                arrayName.add(result.getName());
                arrayValue.add(result.getCount());
            }
        }
        jsonObject.put("X", arrayName);//键名为 X
        jsonObject.put("V", arrayValue);//键名为 V
        return jsonObject;
    }
    /**
     * 按照设备型号，统计出租对多的前20名
     * @return
     */
    @Override
    public JSONObject queryRentTopTenDevice(){
        JSONObject jsonObject = new JSONObject();
        JSONArray arrayName = new JSONArray();
        JSONArray arrayValue = new JSONArray();
        List<ResultMap> resultMaps = rentDeviceLinkMapper.queryRentTopTenDevice();
        if(!CollectionUtils.isEmpty(resultMaps)){
            for(ResultMap result : resultMaps){
                arrayName.add(result.getName());
                arrayValue.add(result.getCount());
            }
        }
        jsonObject.put("X", arrayName);//键名为 X
        jsonObject.put("V", arrayValue);//键名为 V
        return jsonObject;
    }

    /**
     * 归还设备
     * @param param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult returnDevice(RentDeviceLink param){
        RentDeviceLink rentDeviceLink = selectRentDeviceLinkById(param.getId());
        if(RENT_TYPE_RENTING != rentDeviceLink.getValid()){
            return AjaxResult.error("选择归还设备，目前不是已出租状态，不需要归还！");
        }
        RentDeviceLink link = new RentDeviceLink();
        link.setId(rentDeviceLink.getId());
        link.setValid(RENT_TYPE_RETURNED);
        link.setActualRentStartTime(rentDeviceLink.getActualRentStartTime());
        link.setActualRentEndTime(param.getActualRentEndTime());
        AjaxResult ajaxResult = updateRentDeviceLink(link);
        if(AjaxResult.Type.SUCCESS.value() != Integer.parseInt(ajaxResult.get(CODE_TAG).toString())){
            return ajaxResult;
        }
        iEntityDeviceService.returnDevice(rentDeviceLink.getDeviceId());
        return completeRent(rentDeviceLink.getRentId());
    }

    /**
     * 撤销设备
     * @param param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult revokeDevice(RentDeviceLink param){
        RentDeviceLink rentDeviceLink = selectRentDeviceLinkById(param.getId());
        if(RENT_TYPE_RENTING != rentDeviceLink.getValid()){
            return AjaxResult.error("选择归还设备，目前不是已出租状态，不需要撤销！");
        }
        RentDeviceLink link = new RentDeviceLink();
        link.setId(rentDeviceLink.getId());
        link.setValid(RENT_TYPE_REVOKED);
        updateRentDeviceLink(link);
        iEntityDeviceService.returnDevice(rentDeviceLink.getDeviceId());
        return completeRent(rentDeviceLink.getRentId());
    }

    /**
     * 完成出库单
     * @param rentId
     */
    private AjaxResult completeRent(Long rentId){
        AjaxResult result = AjaxResult.success();
        RentDeviceLink rentDeviceLink = new RentDeviceLink();
        rentDeviceLink.setRentId(rentId);
        List<RentDeviceLink> rentDeviceLinks = selectRentDeviceLinkList(rentDeviceLink);
        List<RentDeviceLink>  revokedList = new ArrayList<RentDeviceLink>();
        List<RentDeviceLink>  rentingList = new ArrayList<RentDeviceLink>();
        List<RentDeviceLink>  returnedList = new ArrayList<RentDeviceLink>();
        Date maxActualRentDate = null;
        for(RentDeviceLink link:rentDeviceLinks){
            Integer linkValid = link.getValid();
            if(RENT_TYPE_REVOKED == linkValid){
                revokedList.add(link);
            }else if(RENT_TYPE_RETURNED == linkValid){
                returnedList.add(link);
                Date actualRentEndTime = link.getActualRentEndTime();
                if(null == maxActualRentDate){
                    maxActualRentDate = actualRentEndTime;
                }else if(maxActualRentDate.before(actualRentEndTime)){
                    maxActualRentDate = actualRentEndTime;
                }
            }else if(RENT_TYPE_RENTING == linkValid){
                rentingList.add(link);
            }
        }
        if(0 == rentingList.size()){//所有出库单中的设备已经完成，可以终结该订单
            EntityRent rent = entityRentMapper.selectEntityRentById(rentId);
            if(returnedList.size() >0 ){//存在归还设备，将出库单设置为 已归还状态
                EntityRent entityRent = new EntityRent();
                entityRent.setId(rentId);
                entityRent.setActualRentEndTime(maxActualRentDate);
                entityRent.setActualRentSpan(DateUtils.differentDaysByMillisecond(rent.getActualRentStartTime(),maxActualRentDate)+1);
                entityRent.setValid(RENT_TYPE_RETURNED);
                entityRentMapper.updateEntityRent(entityRent);
                result = AjaxResult.success("订单"+rent.getRentNumber()+"所有设备已经归还，该订单已经完成！");
            }else{//不存在归还设备，将出库单设置为 已撤销状态
                EntityRent entityRent = new EntityRent();
                entityRent.setId(rentId);
                entityRent.setValid(RENT_TYPE_REVOKED);
                entityRentMapper.updateEntityRent(entityRent);
                result = AjaxResult.success("订单"+rent.getRentNumber()+"所有设备已经撤销，该订单已经置为撤销状态！");
            }
        }
        return result;
    }
}
